package ai.people.netmon.framework.domain.archives.vo;

import ai.people.netmon.framework.constant.NumberHideConstant;
import ai.people.netmon.framework.domain.archives.entity.ArchivesBaseInfo;
import ai.people.netmon.framework.domain.archives.entity.ArchivesCompanyInfo;
import ai.people.netmon.framework.domain.archives.entity.ArchivesSocialInfo;
import ai.people.netmon.framework.domain.graph.SocialBaseTag;
import ai.people.netmon.framework.domain.graph.tags.PersonArchivesTag;
import ai.people.netmon.utils.NumberUtils;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import com.people.core.validator.annotation.CompareValid;
import com.people.core.validator.annotation.NumberStatusValue;
import com.people.core.validator.annotation.SourcesValue;
import com.people.core.validator.annotation.WalletsValue;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.hibernate.validator.constraints.Length;

import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 档案返回VO
 *
 * @author zhenglin
 * @since 2022/3/30
 */
@Data
@NoArgsConstructor
public class ArchivesVO {

    /**
     * 主键ID
     */
    @NotNull(message = "id 不能为空")
    @JSONField(serializeUsing = ToStringSerializer.class)
    private Long id;

    /**
     * 姓名
     */
    private List<String> names;

    /**
     * 性别 0:未知, 1:男 ,2:女
     *
     * @mock 1
     */
    @NumberStatusValue(values = {0, 1, 2}, message = "性别值只能为0,1,2")
    private Integer gender;

    /**
     * 照片
     */
    private String picture;

    /**
     * 出生日期
     */
    private String birthday;

    /**
     * 体重
     */
    @CompareValid(compare = CompareValid.Compare.GTE, message = "不能小于0")
    private Double weight;

    /**
     * 身高
     */
    @CompareValid(compare = CompareValid.Compare.GTE, message = "不能小于0")
    private Double height;

    /**
     * 籍贯
     */
    @Length(max = 255, message = "籍贯长度最长为{max}")
    private String hometown;

    /**
     * 现居地
     */
    @Length(max = 255, message = "现居地长度最长为{max}")
    private String residentialAddress;

    /**
     * 爱好
     */
    private String hobby;

    /**
     * 身份证
     *
     * @mock 500000000000000000
     */
    @Length(max = 255, message = "身份证长度最长为{max}")
    private String idNumber;

    /**
     * 护照
     */
    private String passport;

    /**
     * 手机号
     */
    private List<String> phoneNumbers;

    /**
     * 车牌号
     */
    private List<String> plateNumbers;

    /**
     * 标签
     */
    private List<String> tags;

    /**
     * 银行账号
     */
    private List<Bank> bankAccounts;

    /**
     * 教育经历
     */
    private List<Education> educationExperiences;

    /**
     * 就业经历
     */
    private List<Work> workExperiences;

    /**
     * 政治立场
     */
    private String political;

    /**
     * 家庭信息
     */
    private String familySituation;

    /**
     * 个人信息
     */
    private String personalSituation;

    /**
     * 档案研判
     */
    private String archivesJudgment;

    /**
     * 备注
     */
    private String note;

    /**
     * 创建人
     */
    private String creator;

    /**
     * 创建时间
     */
    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    @JSONField(format = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;

    /**
     * 公司信息列表
     */
    @Valid
    CompanyInfo companyInfo;

    /**
     * 社交媒体
     */
    @Valid
    SocialInfo socialInfo;


    public ArchivesVO(ArchivesBaseInfo baseInfo) {
        this.id = baseInfo.getId();
        this.names = baseInfo.buildName();
        this.gender = baseInfo.getGender();
        this.picture = baseInfo.getPicture();
        this.birthday = baseInfo.getBirthday();
        this.weight = baseInfo.getWeight();
        this.height = baseInfo.getHeight();
        this.hometown = baseInfo.getHometown();
        this.residentialAddress = baseInfo.getResidentialAddress();
        this.hobby = baseInfo.getHobby();
        this.idNumber = baseInfo.getIdNumber();
        this.phoneNumbers = baseInfo.buildPhone();
        this.plateNumbers = baseInfo.buildPlate();
        this.tags = baseInfo.buildTags();
        this.bankAccounts = baseInfo.buildBankAccount();
        this.educationExperiences = baseInfo.buildEducationExperience();
        this.workExperiences = baseInfo.buildWorkExperience();
        this.political = baseInfo.getPolitical();
        this.familySituation = baseInfo.getFamilySituation();
        this.personalSituation = baseInfo.getPersonalSituation();
        this.archivesJudgment = baseInfo.getArchivesJudgment();
        this.note = baseInfo.getNote();
        this.createTime = baseInfo.getCreateTime();
        this.updateTime = baseInfo.getUpdateTime();
        this.creator = baseInfo.getCreatorName();
    }

    public ArchivesVO(PersonArchivesTag personArchivesTag, boolean hide) {
        this.names = personArchivesTag.buildNames();
        this.gender = personArchivesTag.getGender();
        this.picture = personArchivesTag.getPicture();
        this.birthday = personArchivesTag.getBirthday();
        this.weight = personArchivesTag.coverWeight();
        this.height = personArchivesTag.coverHeight();
        this.hometown = personArchivesTag.getHometown();
        this.residentialAddress = personArchivesTag.getResidentialAddress();
        this.hobby = personArchivesTag.getHobby();
        this.political = personArchivesTag.getPolitical();
        this.familySituation = personArchivesTag.getFamilySituation();
        this.personalSituation = personArchivesTag.getPersonalSituation();
        this.archivesJudgment = personArchivesTag.getArchivesJudgment();
        this.tags = personArchivesTag.buildTags();
        if (hide) {
            this.idNumber = NumberUtils.hideBit(personArchivesTag.getIdNumber(), NumberHideConstant.ID_HIDE);
            this.passport = NumberUtils.hideBit(personArchivesTag.getPassport(), NumberHideConstant.PASSPORT_HIDE);
        } else {
            this.idNumber = personArchivesTag.getIdNumber();
            this.passport = personArchivesTag.getPassport();
        }
    }

    public ArchivesVO buildArchivesVO(ArchivesAddVO archives, String archivesId) {
        ArchivesVO archivesVO = JSONObject.parseObject(JSONObject.toJSONString(archives), ArchivesVO.class);
        archivesVO.setId(Long.valueOf(archivesId));
        return archivesVO;
    }


    public void companyInfo(ArchivesCompanyInfo companyInfo) {
        this.companyInfo = companyInfo == null ? null : new CompanyInfo(companyInfo);
    }

    public void socialInfo(ArchivesSocialInfo socialInfo) {
        this.socialInfo = socialInfo == null ? null : new SocialInfo(socialInfo);
    }


    @Data
    @NoArgsConstructor
    public static class CompanyInfo {
        /**
         * 名称
         */
        @Length(max = 255, message = "公司名称长度最长为{max}")
//        @NotBlank(message = "公司名称不能为空")
        private String name;

        /**
         * 地址
         */
        @Length(max = 255, message = "公司地址长度最长为{max}")
        private String area;

        /**
         * 成立时间
         */
        private String establishmentTime;

        /**
         * 法定代表人
         */
        @Length(max = 255, message = "公司法定代表人长度最长为{max}")
        private String legalRepresentative;

        /**
         * 股东信息
         */
        @Length(max = 255, message = "公司股东信息长度最长为{max}")
        private String shareholderInfo;

        /**
         * 企业类型
         */
        @Length(max = 255, message = "公司企业类型长度最长为{max}")
        private String enterpriseType;

        /**
         * 工商注册号
         */
        @Length(max = 255, message = "公司工商注册号长度最长为{max}")
        private String icRegistrationNum;

        /**
         * 纳税人识别号
         */
        @Length(max = 255, message = "公司纳税人识别号长度最长为{max}")
        private String taxpayerIdentificationNum;

        /**
         * 纳税人资质
         */
        @Length(max = 255, message = "公司纳税人资质长度最长为{max}")
        private String taxpayerQualification;

        /**
         * 统一社会信用代码
         */
        @Length(max = 255, message = "公司统一社会信用代码长度最长为{max}")
//        @NotBlank(message = "公司统一社会信用代码不能为空")
        private String unifiedSocialCreditCode;

        /**
         * 人员规模
         */
        @Length(max = 255, message = "公司人员规模长度最长为{max}")
        private String personnelScale;

        /**
         * 参保人员
         */
        @Length(max = 255, message = "公司参保人员长度最长为{max}")
        private String insuredPersons;

        /**
         * 登记机关
         */
        @Length(max = 255, message = "公司登记机关长度最长为{max}")
        private String registrationAuthority;

        /**
         * 所属行业
         */
        @Length(max = 255, message = "公司所属行业长度最长为{max}")
        private String industry;

        /**
         * 公司情况
         */
        @Length(max = 255, message = "公司情况长度最长为{max}")
        private String companySituation;

        public CompanyInfo(ArchivesCompanyInfo companyInfo) {
            this.name = companyInfo.getName();
            this.area = companyInfo.getArea();
            this.establishmentTime = companyInfo.getEstablishmentTime();
            this.legalRepresentative = companyInfo.getLegalRepresentative();
            this.shareholderInfo = companyInfo.getShareholderInfo();
            this.enterpriseType = companyInfo.getEnterpriseType();
            this.icRegistrationNum = companyInfo.getIcRegistrationNum();
            this.taxpayerIdentificationNum = companyInfo.getTaxpayerIdentificationNum();
            this.taxpayerQualification = companyInfo.getTaxpayerQualification();
            this.unifiedSocialCreditCode = companyInfo.getUnifiedSocialCreditCode();
            this.personnelScale = companyInfo.getPersonnelScale();
            this.insuredPersons = companyInfo.getInsuredPersons();
            this.registrationAuthority = companyInfo.getRegistrationAuthority();
            this.industry = companyInfo.getIndustry();
            this.companySituation = companyInfo.getCompanySituation();
        }
    }


    public String namesStr() {
        return getString(this.names);
    }

    private static String getString(List<String> list) {
        if (CollectionUtils.isNotEmpty(list)) {
            return Strings.join(list, ',');
        }
        return null;
    }


    private static <T> String getJsonString(List<T> list) {
        if (CollectionUtils.isNotEmpty(list)) {
            return JSONObject.toJSONString(list);
        }
        return null;
    }

    public String phoneNumbersStr() {
        return getString(this.phoneNumbers);
    }


    public String plateNumbersStr() {
        return getString(this.plateNumbers);
    }

    @Data
    public static class Tag {
        /**
         * 标签
         */
        private String tag;

    }

    public String tagsStr() {
        if (CollectionUtils.isNotEmpty(this.tags)) {
            return StringUtils.join(this.tags, ",");
        }
        return null;
    }

    @Data
    public static class Bank {
        /**
         * 银行名称
         *
         * @mock 北京银行
         */
        @Length(max = 255, message = "银行名称长度最长为{max}")
        private String bank;
        /**
         * 银行账户
         */
        @Length(max = 255, message = "银行账户长度最长为{max}")
        private String bankAccount;

    }

    public String bankAccountsJsonStr() {
        return getJsonString(this.bankAccounts);
    }


    @Data
    public static class Education {
        /**
         * 开始时间
         */
        private String startTime;
        /**
         * 结束时间
         */
        private String endTime;

        /**
         * 学校
         *
         * @mock 北京大学
         */
        @Length(max = 255, message = "学校长度最长为{max}")
//        @NotBlank(message = "学校不能为空")
        private String school;

        /**
         * 专业
         *
         * @mock 计算机科学与信息技术
         */
        @Length(max = 255, message = "专业长度最长为{max}")
        private String profession;

        /**
         * 学位
         */
        @Length(max = 255, message = "学位长度最长为{max}")
        private String degree;
    }

    public String educationExperiencesJsonStr() {
        return getJsonString(this.educationExperiences);
    }

    @Data
    public static class Work {
        /**
         * 开始时间
         */
        private String startTime;
        /**
         * 结束时间
         */
        private String endTime;

        /**
         * 公司
         *
         * @mock xx公司
         */
        @Length(max = 255, message = "公司长度最长为{max}")
        private String company;

        /**
         * 职位
         *
         * @mock xx职位
         */
        @Length(max = 255, message = "职位长度最长为{max}")
        private String position;

        /**
         * 收入
         *
         * @mock 1000
         */
        private BigDecimal income;
    }

    public String workExperiencesJsonStr() {
        return getJsonString(this.workExperiences);
    }

    @Data
    @NoArgsConstructor
    public static class SocialInfo {

        /**
         * 社交媒体
         */
        @Valid
        private List<SocialInfoInner> socialInfos;

        /**
         * 电子邮箱
         */
        @Valid
        private List<Email> emailInfo;

        /**
         * 钱包地址
         */
        @Valid
        private List<Wallet> walletInfo;

        /**
         * 数据泄露
         */
        private String dataLeakage;

        public SocialInfo(ArchivesSocialInfo socialInfo) {
            this.socialInfos = socialInfo.buildSocialInfo();
            this.emailInfo = socialInfo.buildSocialEmail();
            this.walletInfo = socialInfo.buildSocialWallet();
            this.dataLeakage = socialInfo.getDataLeakage();
        }

        public String socialInfosJsonStr() {
            return getJsonString(this.socialInfos);
        }

        public String emailInfoJsonStr() {
            return getJsonString(this.emailInfo);
        }

        public String walletInfoJsonStr() {
            return getJsonString(this.walletInfo);
        }

        @Data
        @NoArgsConstructor
        @AllArgsConstructor
        public static class SocialInfoInner {
            /**
             * 社交平台
             *
             * @mock twitter
             */
            @NotBlank(message = "社交平台不能为空")
            @SourcesValue
            @Length(max = 255, message = "社交平台长度最长为{max}")
            private String socialPlatform;

            /**
             * 头像
             */
            private String portrait;

            /**
             * 昵称
             */
            @Length(max = 255, message = "昵称长度最长为{max}")
            private String nickName;

            /**
             * 账号
             */
            @Length(max = 255, message = "账号长度最长为{max}")
            @NotBlank(message = "账号不能为空")
            private String username;
            /**
             * ID
             */
            @Length(max = 255, message = "账号ID长度最长为{max}")
            private String accountId;
            /**
             * url
             */
            private String url;
            /**
             * 密码
             */
            private String password;
            /**
             * 简介
             */
            private String brief;

            public SocialInfoInner(SocialBaseTag socialTag, String tags) {
                this.socialPlatform = tags;
                this.nickName = socialTag.getNickName();
                this.username = socialTag.getUserName();
                this.accountId = socialTag.getUserId();
                this.url = socialTag.getUrls();
                this.password = socialTag.getPassword();
                this.brief = socialTag.getBrief();
            }
        }

        @Data
        public static class Email {
            /**
             * 邮箱名
             *
             * @mock 17722772@163.com
             */
//            @Pattern(regexp = "^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$", message = "邮箱格式错误！")
            @Length(max = 255, message = "邮箱名长度最长为{max}")
            @NotBlank(message = "邮箱名不能为空")
            private String email;
            /**
             * 密码
             *
             * @mock 122..#22
             */
            private String password;
        }

        @Data
        public static class Wallet {
            /**
             * 类型
             */
            @Length(max = 255, message = "类型长度最长为{max}")
            @WalletsValue
            private String coinType;
            /**
             * 地址
             */
            @NotBlank(message = "地址不能为空")
            private String address;
        }
    }


}
